From hyu at stats.uwo.ca  Sat Sep 29 17:26:49 2007
From: hyu at stats.uwo.ca (Hao Yu)
Date: Sat, 29 Sep 2007 11:26:49 -0400 (EDT)
Subject: [Rd] CHAR () and Rmpi
In-Reply-To: <6phtzpdv9gn.fsf@gopher4.fhcrc.org>
References: <65368.65.95.138.11.1191005668.squirrel@www.stats.uwo.ca>
	<Pine.LNX.4.64.0709290655440.19554@gannet.stats.ox.ac.uk>
	<6phtzpdv9gn.fsf@gopher4.fhcrc.org>
Message-ID: <49192.65.95.163.121.1191079609.squirrel@www.stats.uwo.ca>

Thank all for your quick reply. I am wrong to say Rmpi does not modify
CHARSXP at C level. In fact as Martin points out, the receive buff must be
modified. Last night I started the modification of c codes.

For send buffer (no modification), I used
//copy from R 2.6.0 (not in previous versions)
char *acopy_string2(const char *in)
{
    char *out;
    int len = strlen(in);
    if (len > 0) {
        out = (char *) R_alloc(strlen(in), sizeof(char));
        strcpy(out, in);
    } else
        out = "";
    return out;
}

char *charsxp2char(SEXP x)
{
    return acopy_string2(CHAR(x));
}

// I may combine above two functions together

SEXP mpi_info_set(SEXP sexp_info, SEXP sexp_key, SEXP sexp_value){
        char *key, *value;
        key =  charsxp2char( STRING_ELT (sexp_key,0));
        value = charsxp2char (STRING_ELT (sexp_value,0));

        return
AsInt(erreturn(mpi_errhandler(MPI_Info_set(info[INTEGER(sexp_info)[0]],
key, value))));
}

//For modified buffer. Need to use R_alloc for better memory managment
SEXP mpi_info_get(SEXP sexp_info, SEXP sexp_key, SEXP sexp_valuelen){
        int flag;
        char *key, *value;
        SEXP sexp_value;

        key=charsxp2char( STRING_ELT (sexp_key,0));
        PROTECT (sexp_value  = allocVector (STRSXP, 1));
        value = (char *)Calloc(INTEGER(sexp_valuelen)[0], char);
        mpi_errhandler(MPI_Info_get(info[INTEGER(sexp_info)[0]], key,
INTEGER(sexp_valuelen)[0], value, &flag));
        SET_STRING_ELT(sexp_value, 0, mkChar(value));
        UNPROTECT(1);
        Free(value);

        return sexp_value;
}

This works well. However, for nonblock calls, there is no way to receive a
char vector.

I am going to tidy up the codes and remove some redundant codes.

To Prof. Ripley. I am rewriting configure.ac (from configure.in) and put
lib64 in the search path. I am working on Debian 4.0 64bit and the
original configure.ac works well. The new configure.ac can be used for
OpenMPI so Rmpi can be used under OpenMPI (many request it). In addition,
Rmpi can be compiled and run under Mac OS X. I do not know if r-project
will put lam into OS X and make Rmpi officially available to Mac. I need
to fully test Rmpi before submitting next version.

Thanks all and have nice weekend days.
Hao

Martin Morgan wrote:
> Hao Yu,
>
> I spot two types of problematic code. Certainly the memcpy in
> conversions.c:54 and 56 will cause problems, but I'm not sure whether
> those functions are actually used?
>
> The second paradigm is, e.g., Rmpi.c:561
>
>     MPI_Recv(CHAR(STRING_ELT(sexp_data,i)),
>              slen,MPI_CHAR,source,tag, comm[commn],&status[statusn]);
>
> where the first argument to MPI_Recv is a buffer that MPI_Recv will
> fill. sexp_data is a user-supplied character vector. A not-clever
> solution creates a temporary buffer via R_alloc (for garbage-collected
> memory) or R_Calloc (for user-managed memory, probably appropriate in
> a loop where you'd like to reuse the buffer), passes the buffer to
> MPI_Recv, and then SET_STRING_ELT with the now filled temporary buffer
> converted to a CHARSXP with mkChar. I think this is backward
> compatible. The user-supplied character vector has gone to waste, used
> only to pass in the length of the expected string. mkChar will copy
> the temporary buffer (unless an identical CHARSXP already exists), so
> that there are potentially three memory allocations per string!  I
> suspect most users rely on higher-level access (mpi.par*Apply,
> mpi.*.Robj, etc) where this inefficiency is not important or can be
> addressed without modifying the public interface.
>
> Martin
>
> Prof Brian Ripley <ripley at stats.ox.ac.uk> writes:
>
>> I'm not sure what your sticking point here is.  If mpi does not modify
>> data in a (char *) pointer, then that really is a (const char *) pointer
>> and the headers are being unhelpful in not telling the compiler that
>> the data are constant.
>>
>> If that is the case you need to use casts to (char *) and the following
>> private define may be useful to you:
>>
>> #define CHAR_RW(x) ((char *) CHAR(x))
>>
>>
>> However, you ask
>>
>>> Is there an easy way to get a char pointer to
>>> STRING_ELT((sexp_rdata),0)
>>> and is also backward compatible to old R versions.
>>
>> and the answer is that there is no such way, since (const char *) and
>> (char *) are not the same thing and any package that wants to alter the
>> contents of a string element needs to create a new CHARSXP to be that
>> element.
>>
>>
>> BTW, you still have not changed Rmpi to remove the configure problems on
>> 64-bit systems (including assuming libs are in /usr/lib not /usr/lib64)
>> I
>> pointed out a long time ago.
>>
>>
>> On Fri, 28 Sep 2007, Hao Yu wrote:
>>
>>> Hi. I am the maintainer of Rmpi package. Now I have a problem regarding
>>> the change of CHAR () in R 2.6.0. According to R 2.6.0 NEWS:
>>> *******
>>> CHAR() now returns (const char *) since CHARSXPs should no
>>>        longer be modified in place.  This change allows compilers to
>>>        warn or error about improper modification.  Thanks to Herve
>>>        Pages for the suggestion.
>>> *******
>>> Unfortunately this causes Rmpi to fail since MPI requires char pointers
>>> rather than const char pointers. Normally I use
>>>    CHAR(STRING_ELT((sexp_rdata),0))
>>> to get the pointer to MPI where a R character vector (C sense) is
>>> stored.
>>> Because of the change, all character messengers fail. Is there an easy
>>> way
>>> to get a char pointer to STRING_ELT((sexp_rdata),0) and is also
>>> backward
>>> compatible to old R versions. BTW Rmpi does not do any modification of
>>> characters at C level.
>>>
>>> Thanks
>>> Hao Yu
>>>
>>>
>>
>> --
>> Brian D. Ripley,                  ripley at stats.ox.ac.uk
>> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
>> University of Oxford,             Tel:  +44 1865 272861 (self)
>> 1 South Parks Road,                     +44 1865 272866 (PA)
>> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
> --
> Martin Morgan
> Bioconductor / Computational Biology
> http://bioconductor.org
>


-- 
Department of Statistics & Actuarial Sciences
Fax Phone#:(519)-661-3813
The University of Western Ontario
Office Phone#:(519)-661-3622
London, Ontario N6A 5B7
http://www.stats.uwo.ca/faculty/yu



[Rd] CHAR () and Rmpi
Hao Yu